package lee.test.xml;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.w3c.dom.NodeList;

public class XpathDemo {     
        /** 
         * 已知命名空间，获得该命名空间下节点 
         * @throws Exception 
         */  
        public static void test1() throws Exception {  
            SAXReader reader = new SAXReader();  
            String uri = "http://WebXml.com.cn/";//命名空间  
            HashMap map = new HashMap();//将uri存入map中  
            map.put("xx", uri);  
            reader.getDocumentFactory().setXPathNamespaceURIs(map);  
              
            InputStream is = new FileInputStream("src/a.xml");  
                org.dom4j.Document document = reader.read(is);  
                  
            org.dom4j.XPath xpath = DocumentHelper.createXPath("//xx:string");  
              
            List list = xpath.selectNodes(document);//等价List list = document.selectNodes("//xx:string");  
            for(int i=0; i<list.size(); i++){  
                Node node = (Node)list.get(i);//转型为Node  
                System.out.println("hah====="+node.getText());  
                  
                Element e = (Element)list.get(i);//转型为Element  
                System.out.println(e.getText());  
            }  
        }  
      
        /** 
         * 先通过document获得命名空间，再获得该命名空间下节点 
         * @throws Exception 
         */  
        public static void test2()  throws Exception {  
            SAXReader reader = new SAXReader();  
            InputStream is = new FileInputStream("src/a.xml");  
            org.dom4j.Document document = reader.read(is);  
              
            //获得节点的命名空间  
            String uri = document.getRootElement().element("Body")  
                    .element("getWeatherbyCityNameResponse").getNamespaceURI();  
            //将uri存入map中  
            HashMap map = new HashMap();  
            map.put("xx", uri);  
              
            org.dom4j.XPath xpath = DocumentHelper.createXPath("//xx:string");  
            xpath.setNamespaceURIs(map);  
              
            List list = xpath.selectNodes(document);  
            for(int i=0; i<list.size(); i++){  
                Node node = (Node)list.get(i);//转型为Node  
                System.out.println("hah====="+node.getText());  
                  
                Element e = (Element)list.get(i);//转型为Element  
                System.out.println(e.getText());  
            }  
       }  
        
        public static List getSecondMenuNames(String textName, String path,  
                String userName) {  
            String xmlName = path + "/" + userName + ".xml";  
            String name = textName;  
            // 定义需要返回的第二级菜单的名字集合  
            List firstNames = new ArrayList();  
            // Attribute的属性集合  
            List attrs = new ArrayList();  
            // 声明SAXReader  
            SAXReader saxReader = new SAXReader();  
            try {  
                Document doc = saxReader.read(xmlName);  
                // 这个xpath的意思是,获取text='系统管理'的一个Item下的所有Item的节点  
                String xpath = "//item[@text='" + name + "']/child::*";  
      
                List list = doc.selectNodes(xpath);  
                Iterator it = list.iterator();  
                while (it.hasNext()) {  
                    Element elt = (Element) it.next();  
//                    elt.setText(text);
                }  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
            return attrs;  
        }  

        
         
       /** 
        * 运用jdk中自带包javax.xml.xpath包 
        * @throws Exception 
        */  
       public static void test3()  throws Exception {  
        //将XML文档加载到DOM Document对象中  
           DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();     
           factory.setNamespaceAware(true); // never forget this!     
           DocumentBuilder builder = factory.newDocumentBuilder();     
           org.w3c.dom.Document doc = builder.parse("src/books.xml");     
           //创建 XPathFactory  
           XPathFactory pathFactory = XPathFactory.newInstance();     
           //使用XPathFactory工厂创建 XPath 对象  
           XPath xpath = pathFactory.newXPath();     
           //使用XPath对象编译XPath表达式  
           XPathExpression pathExpression = xpath     
                           .compile("//book[author='TEST']/title/text()");     
           //计算 XPath 表达式得到结果  
           Object result = pathExpression.evaluate(doc, XPathConstants.NODESET);     
           //节点集node-set转化为NodeList  
           //将结果强制转化成 DOM NodeList   
           org.w3c.dom.NodeList nodes = (NodeList) result;     
           for (int i = 0; i < nodes.getLength(); i++) {     
                   System.out.println(nodes.item(i).getNodeValue());     
           }  
           //查找所有图书的 XPath 查询非常简单:  
           //book[author="TEST"]     
           //book代表节点的名称,author属性的名称,后面是要查询的值    
             
           //为了找出这些图书的标题(title),只要增加一步,表达式就变成了:  
           //book[author="TEST"]/title     
           //title代表要取元素的名称    
             
           //最后,真正需要的是 title 元素的文本节点内容.这就要求再增加一步,完整的表达式就是:  
           //book[author="TEST"]/title/text()     
           //text()该节点的内容    
       }  
         
       public static void main(String[] args) throws Exception{  
           test1();  
           //test2();  
           //test3();  
       }     
}  